DeepLink

唤端技术背景

在日常开发中,往往需要通过唤端改善用户体验。比如一个常见的场景:用户通过链接分享或其他途径,在端外访问 H5 活动页面,与页面发生交互后,需要实现以下功能:

功能 A 和 B 可通过 DeepLink 或 AppLink 实现;功能 C 可通过 Deferred DeepLink 实现。
有了这项技术我们就可以实现 H5 唤起 APP 应用、Facebook App 的广告到自己的 App 了,现阶段的引流方式大都得益于这种技术,比如广告投放、用户拉新等
目前主要有这几种技术:

  1. Deeplink 用于 APP 间的跳转,如果是浏览器,可能会有二次弹窗确认;如果有多个组件能处理该 deeplink,都会弹窗列举出来供你选择
  2. Applinks(Universal Link) 用于消除 Deeplink 的二次弹窗选择,直接到达你的 APP
  3. Defered DeepLink 延迟的 deeplink,首次安装会去拉一个接口返回一些安装来源信息或 deeplink;一般用于首次安装确认来源的,如Google install referer,Facebook ad defered deeplinkgoogle ad deferer deeplink, appsflyer deferer deeplink

Deeplink

URL Scheme,多一次二次弹窗选择

平时说的 Deeplink,在 Android 上就是 URL Scheme。

添加 Intent-Filter

  1. 定义 URI Scheme
<activity
  android:name=".ui.activity.SplashActivity"
  android:exported="true"
  android:screenOrientation="portrait"
  android:theme="@style/NormalSplash">

  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>

  <!--DeepLink h5唤醒app配置-->
  <intent-filter>
    <!--ACTION_VIEW:支持被检索-->
    <action android:name="android.intent.action.VIEW" />
    <!--CATEGORY_DEFAULT:响应隐式Intent-->
    <category android:name="android.intent.category.DEFAULT" />
    <!--CATEGORY_BROWSABLE:可被Web浏览器唤起-->
    <category android:name="android.intent.category.BROWSABLE" />
    <!--data:一个或多个,必须含有scheme标签,决定被唤起的URL格式-->
    <data
      android:host="me.hacket"
      android:scheme="hacket" />
    <!--    
    <data
    android:host="me.hacket"
    android:scheme="hacket" 
    android:pathPrefix="/pxwx"/>
    <data
    android:host="me.hacket"
    android:scheme="hacket" 
    android:path="/pxwx/user"/>
    -->
  </intent-filter>
</activity>
  1. Uri 数据的解析可以在你的 SlashActivity 中通过 getIntent().getData() 实现
@Override 
public void onCreate(Bundle savesInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);
    
    // 尝试获取WebApp页面上过来的URL
    Uri uri = getIntent().getData();
    if (uri != null) {
        // scheme部分
        String scheme=data.getScheme();
        // host部分
        String host=data.getHost();
        // 访问路径
        String path=data.getPath();
        //参数
        Set<String> paramKeySet=data.getQueryParameterNames();
    }
}
  1. 在 h5 页面上,通过如下方式使用:
<!--1.通过a标签打开,点击标签是启动-->
<!-- 注意这里的href格式 -- >
<a href="hacket://app.me.hacket">open android app</a>

<!--2.通过iframe打开,设置iframe.src即会启动-->
<iframe src="hacket://me.hacket"></iframe>

<!--3.直接通过window.location 进行跳转-->
window.location.href= "hacket://me.hacket";
  1. 在原生 App 中唤起通过 Intent 方式
Intent intent = new Intent();
intent.setData(Uri.parse("hacket://me.hacket/"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
  1. 用户点击了链接后,会弹出一个列举了能处理该链接的 Dialog 供用户选择(所有能处理该链接的 APP)

833bn

测试 URL Scheme

adb 命令

adb shell am start -W -a android.intent.action.VIEW -d "yourdeeplink://example.com/path?id=123"

如:adb shell am start -W -a android.intent.action.VIEW -d "hacket://hacket.me?name=大圣 "

代码验证

data 为你的测试链接

Intent intent = new Intent();
intent.setData(Uri.parse("hacket://me.hacket/"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

html

放 APP 本地或放到 web 容器 (如 tomcat) 去

<a href='sheinlink://applink/ad_landing_recommend?data={"tsp_id":"60007289","goods_id":"2329783","page_type":"B","mall_code":1}'>B类型:sheinlink://applink/ad_landing_recommend?data={"tsp_id":"60007289","goods_id":"2329783","page_type":"B","mall_code":1}</a>

三方 APP

Via 浏览器,或者添加一个 function,添加 .zshrc/.bach_profile 文件中,模拟操作

#### 启动via app mark.via.gp/mark.via.Shell,然后输入文本,最后按回车键
#### 可用来测试deeplink跳转
function adb:via() {
  echo "stop Via app."
  adb shell am force-stop mark.via.gp
  
  echo "start Via app."
  adb shell am start -n mark.via.gp/mark.via.Shell
  
  sleep 2
  echo "input tap 500 1033"
  # 模拟按2次tab键盘到tab,才能定位到EditText,好像经常找不到焦点
  # adb shell input keyevent KEYCODE_TAB
  # adb shell input keyevent KEYCODE_TAB
  adb shell input tap 500 1033 

  echo "input text $1"
  adb shell input text "$1"

  echo "send keyevent KEYCODE_ENTER"
  adb shell input keyevent KEYCODE_ENTER
}

可以根据不同的手机将坐标替换下

URL Scheme 兼容性

URL Scheme 兼容性高,但却存在许多限制:

三方 APP 唤端的限制

在部分 APP 内部去唤起第三方 APP,第一方 APP 出于防止流量流失、安全性等考虑,对上述 Deeplink 进行了限制,无法直接使用。因此往往是通过第一方 APP 提供的 API 进行唤端,比如微信的 launchApplication、wx-open-launch-app 等。其它 APP 的 API 形式唤端亦是如此

Web links are deep links that use the HTTP and HTTPS schemes.

<intent-filter>
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.BROWSABLE" />

  <data android:scheme="http" />
  <data android:host="myownpersonaldomain.com" />
</intent-filter>
  1. Android12 或以上,点击 web links 会跳转到浏览器
  2. Android12 之前,如果手机上的 APP 能处理该 web links,就会像 deep links 一样弹窗来让用户选择

URL Scheme 存在一个问题就是如果没有 APP 能处理该链接,点击无响应或跳转到一个错误界面;Chrome Intent 就可以在链接无法处理时跳转到一个指定的链接

Chrome Intent 介绍

intent:  
   HOST/URI-path // Optional host  
   #Intent;  
      package=\[string\];  
      action=\[string\];  
      category=\[string\];  
      component=\[string\];  
      scheme=\[string\];  
   end;

示例:sheinlink://applink/sheinGals
不带 browser_fallback_url:

<a href="intent://applink/sheinGals/#Intent;scheme=sheinlink;package=com.zzkko;end">open Shein App sheinGals</a>

在 Android Chrome 115 版本,不带 browser_fallback_url,会跳转到 Google Play

带 browser_fallback_url:

<a href="intent://applink/sheinGals/#Intent;scheme=sheinlink;package=com.zzkko;S.browser_fallback_url=https://www.shein.com;end">open Shein App sheinGals page fallback</a>

这样如果没有对应应用,该链接就会跳转到 S.browser_fallback_url 指定的 url 上。

Chrome Intent 兼容性

deeplink: sheinlink://applink/{跳转类型}?data={参数字典的字符串并进行urlencode}

example:
sheinlink://applink/selectcategory?data=%7b%27category_id%27%3a%27123%27%2c%27attr_ids%27%3a%27101_725-238_102%27%7d

slink: [<schema>://<host>]/<group>/<name>[?need_login=true&data=url_encode({json})]

example:
sheinlink://shein.com/goods/flash_sale_list?data={"id":123, "key":456}
romwelink://romwe.com/goods/flash_sale_list?data=

简单一句话就是从一条短链通过接口转换成 deeplink

注意

slink 需要加白名单,否则只能跳转到首页

  1. onelink(会通过接口返回 deeplink)/deeplink 跳转的: 只支持 1 次 url encode 的,不支持 2 次 url encode 的
  2. Google play install referer/facebook google ddl 带 utm_shein_onelink 的这种:Android 端会在调用 link/onelink/uniParser 接口后做 1 次 url decode
    a. 如果返回的 deeplink 没有&字符,支持后端 1 次或 2 次 encode 的,因为多次 url decode 也可以
    b. 如果返回的 deeplink 有&字符,后端只能 2 次 url encode,如果只进行 1 次 url encode,APP url decode 1 次后,再进去获取 data 后的参数获取不到

onelink 的域名是 applink

方案对比

URL Scheme Universal Link App Link
<ios9 支持 不支持 不支持
>=ios9 支持 支持 不支持
<android6 支持 不支持 不支持
>=android6 支持 不支持 支持
是否需要 HTTPS 不需要 需要 需要
是否需要客户端 需要 需要 需要
无对应 APP 时的现象 报错/无反应 跳到对应的页面 跳到对应的页面

URI Scheme

Ref

对 deeplink/Applink 的发展讲的很清晰